home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Celestin Apprentice 7
/
Apprentice-Release7.iso
/
Source Code
/
Pascal
/
Snippets
/
PNL Libraries
/
Assembly
/
FastFind.a
< prev
next >
Wrap
Text File
|
1994-08-04
|
6KB
|
352 lines
STRING ASIS
Debug: set 0
LinkAll: set 1
LOAD 'ProgStrucMacs.d'
LOAD 'FlowCtlMacs.d'
findRecord record 0
size ds.l 1
datap ds.l 1
word ds.b 64
rn ds.w 1
filelen ds.l 1
pos ds.l 1
count ds.l 1
di ds.l 1
skip ds.b 256
endr
proc Main
; function FastFind(p:ptr) : longInt;
Export FUNCTION FastFind(p:L):L
VAR wi:W, oe:W, pb:$40
BEGIN SAVE=D3-D7/A2-A4,WITH=(findRecord)
; p = A4
; datap = a2
; data_index = D7
; word_index = D6
; count = d5
; amount = ch = d4 (local, temporary)
; length(word) = d3
move.l p(a6),a4
move.l datap(a4),a2
move.l di(a4),d7
move.l count(a4),d5
clr.l d3
move.b word(a4),d3
; oe := noErr;
move.w #0,oe(a6)
; wi := length(word);
move.l d3,d6
; while (oe = noErr) and (wi <> 0) and (pos + data_index < filelen) do begin
loop
tst.w oe(a6)
bne while_exit
tst.l d6
beq while_exit
move.l pos(a4),d0
add.l d7,d0
move.l filelen(a4),d1
cmp.l d0,d1
bls while_exit
; if data_index > count then begin
cmp.l d7,d5
bhs.s if_end
; amount := count - data_index + length(word);
move.l d5,d4
sub.l d7,d4
add.l d3,d4
; pos := pos + count - amount;
move.l d5,d0
sub.l d4,d0
add.l d0,pos(a4)
; BlockMove(@datap^[data_index - length(word) + 1], ptr(datap), amount);
move.l a2,a0
add.l d7,a0
add.l d3,a0
; add.l #1,a0
; sub.l #1,a0 ; base of datap^ is 1
move.l a2,a1
move.l d4,d0
sub.l #1,d0
bmi.s block_move_exit
block_move
move.b (a0)+,(a1)+
dbf d0,block_move
block_move_exit
; data_index := length(word);
move.l d3,d7
; count := size - amount;
move.l size(a4),d5
sub.l d4,d5
; oe := FSRead(rn, count, @datap^[amount + 1]);
; if oe=eofErr then oe:=noErr;
lea pb(a6),a0
move.l a1,$20(a0)
move.w rn(a4),$18(a0)
move.l d5,$24(a0)
clr.w $2c(a0)
clr.l $2e(a0)
dc.w $A002 ; _Read
cmp.w #-39,d0
bne.s @5
clr.w d0
@5 move.w d0,oe(a6)
move.l $28(a0),d5
; count := count + amount;
add.l d4,d5
; end;
if_end
; if (data_index > count) and (oe = noErr) then
; oe := -1;
move.w oe(a6),d0
cmp.l d7,d5
bhs.s no_err
tst.w d0
bne.s no_err
move.w #-1,d0
move.w d0,oe(a6)
no_err
;if oe = noErr then begin
tst.w d0
bne.s give_up
lea -1(a2,d7.l),a0
lea word(a4),a1
lea (a1,d3.w),a3
lea (a1,d6.w),a1
move.l d3,d0 ; d0 = length(word) - wi + 1
sub.w d6,d0
add.w #1,d0
clr.w d4
clr.l d1
; repeat
; ch := UpCase(datap^[data_index]);
; if ch = word[wi] then begin
; data_index := data_index - 1;
; wi := wi - 1;
; if wi=0 then leave;
; end else begin
; data_index := data_index + max(length(word) - wi + 1, skip[ch]);
; wi := length(word);
; if data_index>count then leave
; end;
; until false
inner_loop
move.b (a0),d4
cmp.b #'a',d4
bcs.s @1
cmp.b #'z'+1,d4
bcc.s @1
sub.b #$20,d4
@1
cmp.b (a1),d4
beq.s match
move.b skip(a4,d4.w),d1
cmp.w d0,d1
bge.s @2
move.l d0,d1
@2 add.l d1,d7
add.l d1,a0
move.l d3,d6
move.l #1,d0
move.l a3,a1
cmp.l d7,d5
bhs.s inner_loop
bra.s end_inner_loop
match
sub.l #1,d7
sub.l #1,a0
sub.l #1,a1
add.l #1,d0
sub.w #1,d6
bne.s inner_loop
end_inner_loop
; end;
give_up
; end;
bra.s loop
while_exit
; if wi <>0 then begin
tst.w d6
beq.s yeah
; if oe >= 0 then
; oe := -1;
; Find := oe;
move.w oe(a6),d0
ext.w d0
tst.l d0
bmi.s @3
move.l #-1,d0
@3
; end
bra.s yeah_end
; else begin
yeah
; data_index := data_index + 1;
add.l #1,d7
; Find := pos + data_index;
move.l pos(a4),d0
add.l d7,d0
; data_index := data_index + length(word);
add.l d3,d7
; end;
yeah_end
move.l d7,di(a4)
move.l d5,count(a4)
RETURN D0
ENDP
END
asm -wb "{active}" -i "{MPW}AStructMacs"
Max
move.l (sp)+,d0
move.l (sp)+,d1
cmp.l d0,d1
bge @4
move.l d0,d1
@4 move.l d1,(sp)
rts
Find link a6,
; inline function UpCase(ch:char) : char;
move.w (sp)+,d0
cmp.b #'a',d0
bcs @1
cmp.b #'z'+1,d0
bcc @1
sub.b #$20,d0
@1 move.w d0,(sp)
rts
cd "{MPW}AStructMacs"
files "{MPW}AStructMacs"
FlowCtlMacs.a
Instructions
ProgStrucMacs.a
Sample.a
Sample.make
Sample.r
type
dataArray = packed array[1..1000000] of char;
wordType = str63;
findRecord = record
size: longInt;
datap: ^dataArray;
word: wordType;
rn: integer;
filelen, pos, count, data_index: longInt;
skip: packed array[char] of byte;
data: integer;
end;
findPtr = ^findRecord;
function Find (p: ptr): longInt;
var
oe: OSErr;
amount: 0..63;
ch: char;
wi: integer;
begin
with findPtr(p)^ do begin
oe := noErr;
wi := length(word);
while (oe = noErr) and (wi >= 1) and (pos + data_index < filelen) do begin
{ data_index is the last character in data that we are checking now }
if data_index > count then begin
amount := count - (data_index - length(word));
pos := pos + count - amount;
BlockMove(@datap^[data_index - length(word) + 1], ptr(datap), amount);
data_index := length(word);
count := size - amount;
oe := FSRead(rn, count, @datap^[amount + 1]);
count := count + amount;
end;
if (data_index > count) and (oe = noErr) then
oe := -1;
if oe = noErr then begin
while (data_index <= count) and (wi >= 1) do begin
ch := UpCase(datap^[data_index]);
if ch = word[wi] then begin
data_index := data_index - 1;
wi := wi - 1;
end
else begin
if length(word) - wi + 1 > skip[ch] then
data_index := data_index + length(word) - wi + 1
else
data_index := data_index + skip[ch];
wi := length(word);
end;
end;
end;
end;
if wi >= 1 then begin
if oe >= 0 then
oe := -1;
Find := oe;
end
else begin
Find := pos + data_index + 1;
data_index := data_index + length(word) + 1;
end;
end;
end;